/**
 * 
 */
package freedom.needle.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import freedom.needle.dao.BaseDao;

/**
 * @author charlie
 *
 */
public abstract class BaseDaoImpl<E> extends HibernateDaoSupport implements BaseDao<E> {

	public abstract Class<E> getEntityClass();
	
	@Override
	public final E get(Serializable identifier) {
		E object = this.currentSession().get(this.getEntityClass(), identifier);
		return object;
	}
	
	@Override
	public final E find(Object primaryKey) {
		E object = this.currentSession().find(this.getEntityClass(), primaryKey);
		return object;
	}

	@Override
	public List<E> select(String hql, Object[] params) {
		return select(hql, params, -1, -1);
	}
	
	@Override
	public List<E> select(String hql, Object[] params, int maxResult) {
		return select(hql, params, 0, maxResult);
	}

	@Override
	public List<E> select(String hql, Object[] params, int startPosition, int maxResult) {
		Query<E> query = this.currentSession().createQuery(hql, this.getEntityClass());
		if (params != null)
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i + 1, params[i]);
			}
		if (startPosition >= 0)
			query.setFirstResult(startPosition);
		if (maxResult >= 0)
			query.setMaxResults(maxResult);
		List<E> list = query.getResultList();
		return list;
	}
	
	@Override
	public final List<E> selectBySql(String sql, Object[] params) {
		return selectBySql(sql, params, -1, -1);
	}
	
	@Override
	public final List<E> selectBySql(String sql, Object[] params, int maxResult) {
		return selectBySql(sql, params, 0, maxResult);
	}
	
	@Override
	public final List<E> selectBySql(String sql, Object[] params, int startPosition, int maxResult) {
		NativeQuery<E> query = this.currentSession().createNativeQuery(sql, this.getEntityClass());
		if(params != null)
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i + 1, params[i]);
			}
		if (startPosition >= 0)
			query.setFirstResult(startPosition);
		if (maxResult >= 0)
			query.setMaxResults(maxResult);
		return query.getResultList();
	}
	
	@Override
	public final int update(String hql, Object[] params) {
		Query<?> query = this.currentSession().createQuery(hql);
		if(params != null)
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i + 1, params[i]);
			}
		return query.executeUpdate();
	}

	@Override
	public final int updateBySql(String sql, Object[] params) {
		NativeQuery<?> query = this.currentSession().createNativeQuery(sql);
		if(params != null)
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i + 1, params[i]);
			}
		return query.executeUpdate();
	}

	@Override
	public final void save(E object) {
		this.currentSession().save(object);
	}

	@Override
	public final void save(List<E> objects) {
		for (E e : objects) {
			this.currentSession().save(e);
		}
	}

}
